﻿using UnityEngine;
using System.Collections;
using UnityEditor;
using System;

namespace Hont.HyperWigglePackage.Editor
{
    public class RandomWiggleBuilder : BaseWigglePlugins
    {
        bool mEnablePositionX;
        bool mEnablePositionY;
        bool mEnablePositionZ;
        bool mEnableRotationX;
        bool mEnableRotationY;
        bool mEnableRotationZ;

        PRPair[] mCacheData;
        float mWiggleValue;
        AnimationCurve mCurve;
        Camera mCamera;

        Vector3 mCameraCachePosition;
        Quaternion mCameraCacheRotation;

        bool mIsLocked;


        public override void Execute(HyperWiggleEditorCore core)
        {
            base.Execute(core);

            mCamera = mCore.View.PreviewRenderUtility.camera;

            mCameraCachePosition = mCamera.transform.position;
            mCameraCacheRotation = mCamera.transform.rotation;

            mCore.IsStopCameraControl = true;

            mCurve = new AnimationCurve(new Keyframe(0, 0), new Keyframe(0.5f, 1), new Keyframe(1, 0));
        }

        protected override void OnExit()
        {
            mCore.IsStopCameraControl = false;
        }

        protected override void OnGUI()
        {
            mEnablePositionX = EditorGUILayout.Toggle("Enable Position.x", mEnablePositionX);
            mEnablePositionY = EditorGUILayout.Toggle("Enable Position.y", mEnablePositionY);
            mEnablePositionZ = EditorGUILayout.Toggle("Enable Position.z", mEnablePositionZ);
            mEnableRotationX = EditorGUILayout.Toggle("Enable Rotation.x", mEnableRotationX);
            mEnableRotationY = EditorGUILayout.Toggle("Enable Rotation.y", mEnableRotationY);
            mEnableRotationZ = EditorGUILayout.Toggle("Enable Rotation.z", mEnableRotationZ);

            mCurve = EditorGUILayout.CurveField("Curve: ", mCurve);
            mWiggleValue = EditorGUILayout.Slider("Wiggle Value: ", mWiggleValue, -40f, 40f);

            GUILayout.BeginHorizontal();
            if (GUILayout.Button("Cancel"))
            {
                mCamera.transform.position = mCameraCachePosition;
                mCamera.transform.rotation = mCameraCacheRotation;
                mCacheData.CopyTo(mCore.FrameData, 0);

                mCore.UpdatePreview();
                mCore.UpdateTimeline();
                mIsLocked = false;
                mCore.IsStopCameraControl = true;
            }

            if (GUILayout.Button("Apply"))
            {
                mCacheData = new PRPair[mCore.FrameData.Length];
                mCore.FrameData.CopyTo(mCacheData, 0);

                for (int i = 0; i < mCore.FrameData.Length; i++)
                {
                    var current = i / (float)mCore.EndFrame;
                    var curveValue = mCurve.Evaluate(current) * mWiggleValue;
                    var newPosition = new Vector3();
                    var newRotation = new Vector3();

                    if (mEnablePositionX)
                        newPosition.x = UnityEngine.Random.Range(-curveValue, curveValue);
                    if (mEnablePositionY)
                        newPosition.y = UnityEngine.Random.Range(-curveValue, curveValue);
                    if (mEnablePositionZ)
                        newPosition.z = UnityEngine.Random.Range(-curveValue, curveValue);

                    if (mEnableRotationX)
                        newRotation.x = UnityEngine.Random.Range(-curveValue, curveValue);
                    if (mEnableRotationY)
                        newRotation.y = UnityEngine.Random.Range(-curveValue, curveValue);
                    if (mEnableRotationZ)
                        newRotation.z = UnityEngine.Random.Range(-curveValue, curveValue);

                    newPosition = HyperWiggleUtil.Round(newPosition, 2);
                    newRotation = HyperWiggleUtil.Round(newRotation, 2);

                    mCore.FrameData[i].RelativePosition += newPosition;
                    mCore.FrameData[i].RelativeRotation += newRotation;
                }

                HyperWiggleUtil.StableOffset(mCore.FrameData);

                mCore.UpdatePreview();
                mCore.UpdateTimeline();
                mIsLocked = true;
                mCore.IsStopCameraControl = false;
            }

            GUILayout.EndHorizontal();

            if (!mIsLocked)
            {
                var newPosition = new Vector3();
                var newRotation = new Vector3();

                if (mEnablePositionX)
                    newPosition.x = UnityEngine.Random.Range(-mWiggleValue, mWiggleValue);
                if (mEnablePositionY)
                    newPosition.y = UnityEngine.Random.Range(-mWiggleValue, mWiggleValue);
                if (mEnablePositionZ)
                    newPosition.z = UnityEngine.Random.Range(-mWiggleValue, mWiggleValue);

                if (mEnableRotationX)
                    newRotation.x = UnityEngine.Random.Range(-mWiggleValue, mWiggleValue);
                if (mEnableRotationY)
                    newRotation.y = UnityEngine.Random.Range(-mWiggleValue, mWiggleValue);
                if (mEnableRotationZ)
                    newRotation.z = UnityEngine.Random.Range(-mWiggleValue, mWiggleValue);

                mCamera.transform.position = mCameraCachePosition + newPosition;
                mCamera.transform.eulerAngles = mCameraCacheRotation.eulerAngles + newRotation;
            }
        }
    }
}